package com.example.transaction.sys.service.impl;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.transaction.common.utils.JwtUtil;
import com.example.transaction.sys.entity.User;
import com.example.transaction.sys.mapper.UserMapper;
import com.example.transaction.sys.service.IUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author zh
 * @since 2023-06-20
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private JwtUtil jwtUtil;

    private final UserMapper userMapper; // 假设使用MyBatis Plus的Mapper接口

    public UserServiceImpl(UserMapper userMapper) {
        this.userMapper = userMapper;
    }

    @Override
    public Map<String, Object> login(User user) {
        //根据用户名进行查询
        LambdaQueryWrapper<User>wrapper=new LambdaQueryWrapper<>();
        wrapper.eq(User::getUsername,user.getUsername());
        User loginUser=this.baseMapper.selectOne(wrapper);
        //结果不为空，并且密码和传入的密码匹配，则生成token，并将用户信息存入redis
        if(loginUser!=null&&passwordEncoder.matches(user.getPassword(),loginUser.getPassword())){
            //暂时使用uuid，终极方案是jwt
            //String key="user:"+ UUID.randomUUID();

            //创建jwt
            String token=jwtUtil.createToken(loginUser);

            //存入redis
            loginUser.setPassword(null);
//            redisTemplate.opsForValue().set(token,loginUser,30,TimeUnit.MINUTES);
            //返回数据
            Map<String,Object>data=new HashMap<>();
            data.put("token",token);
            return data;
        }
        return null;
    }

    @Override
    public Map<String, Object> getUserInfo(String token) {
        //根据token来获取用户信息，从redis获取
//        Object obj=redisTemplate.opsForValue().get(token);

        //从jwt获取
        User loginUser=null;
        try{
            loginUser=jwtUtil.parseToken(token,User.class);
        }catch (Exception e){
            e.printStackTrace();;
        }
        //反序列化
        if(loginUser!=null){
            //User loginUser=JSON.parseObject(JSON.toJSONString(obj),User.class);
            Map<String, Object>data=new HashMap<>();
            data.put("userID",loginUser.getUserID());
            data.put("name",loginUser.getUsername());
            data.put("userType",loginUser.getUserType());
            return data;
        }
        return null;
    }

    @Override
    public void logout(String token) {
//        redisTemplate.delete(token);
    }


    @Override
    public boolean changePassword(User user, String currentPassword, String newPassword) {
        //根据用户名进行查询
        LambdaQueryWrapper<User>wrapper=new LambdaQueryWrapper<>();
        wrapper.eq(User::getUsername,user.getUsername());
        User loginUser=this.baseMapper.selectOne(wrapper);
        System.out.println(loginUser);
        System.out.println(currentPassword);
        if(loginUser!=null&&passwordEncoder.matches(currentPassword,loginUser.getPassword())){
            loginUser.setPassword(passwordEncoder.encode(newPassword));
            this.baseMapper.updateById(loginUser);
            return true;
        }
        return false;
    }

    @Override
    public List<Integer> getUserIdsByUsername(String username) {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("Username", username);
        List<User> users = userMapper.selectList(wrapper);
        return users.stream()
                .map(User::getUserID)
                .collect(Collectors.toList());
    }

    @Override
    public List<Integer> getUserIdsByUsernameLike(String userName) {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(User::getUsername, userName);
        List<User> userList = userMapper.selectList(wrapper);
        return userList.stream()
                .map(User::getUserID)
                .collect(Collectors.toList());
    }


}
